using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Acms.SqlDal;

namespace Acms.Bll
{
    public class Topic : BaseItem
    {
        private Topic() : base() { }
        private Topic(Hashtable table) : base(table) { }
        private Topic(Hashtable table, List<Topic> collection) : base(table, collection) { }

        protected override Base CreateDal()
        {
            return new TopicDal();
        }
        
        public static Topic CreateInstance()
        {
            return new Topic();
        }

        private static Topic Get(Hashtable table)
        {
            if (table == null)
            {
                return null;
            }
            else
            {
                return new Topic(table);
            }

        }

        private static List<Topic> Get(Hashtable[] tables)
        {
            if (tables == null)
            {
                return null;
            }
            else
            {
                List<Topic> tmp = new List<Topic>();
                foreach (Hashtable table in tables)
                {
                    tmp.Add(new Topic(table, tmp));
                }
                return tmp;
            }
        }

        public static Topic GetById(int id)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetById(id));
        }

        public static Topic GetBySiteIdTopicGroupPathAndName(int siteId, string topicGroupPath, string name)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetBySiteIdTopicGroupPathAndName(siteId, topicGroupPath, name));
        }

        public static List<Topic> GetAllBySiteId(int siteId)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetAllBySiteId(siteId));
        }

        public static List<Topic> GetAllByPostId(int postId)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetAllByPostId(postId));
        }

        public static List<Topic> GetAllByTopicGroupId(int topicGroupId)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetAllByTopicGroupId(topicGroupId));
        }

        public static List<Topic> GetAllBySiteIdAndTopicGroupPath(int siteId, string path)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetAllBySiteIdAndTopicGroupPath(siteId, path));
        }

        public static List<Topic> GetAllByPostIdAndTopicGroupPath(int postId, string topicGroupPath)
        {
            TopicDal dal = new TopicDal();
            return Get(dal.GetAllByPostIdAndTopicGroupPath(postId, topicGroupPath));
        }

        
        protected override void Load(System.Collections.Hashtable table)
        {
            Id = (int)table[TopicDal.Fields.Id];
            TopicGroupId = (int)table[TopicDal.Fields.TopicGroupId];
            TopicGroupName = (string)table[TopicDal.Fields.TopicGroupName];
            Name = (string)table[TopicDal.Fields.Name];
            Created = (DateTime)table[TopicDal.Fields.Created];
            sequence = (int)table[TopicDal.Fields.Sequence];
            FileCount = (int)table[TopicDal.Fields.FileCount];
        }

        public int Id { get; private set; }
        public int TopicGroupId { get; set; }
        public string TopicGroupName { get; private set;}
        public string Name { get; set; }

        private int sequence = -1;
        public int Sequence
        {
            get { return sequence; }
            set { sequence = value; }
        }

        public int FileCount { get; private set; }
        public DateTime Created { get; private set; }

        private Dictionary<string, TopicFile> topicFiles;
        public TopicFile GetAttachment(string attachmentName)
        {
            if (topicFiles == null)
            {
                topicFiles = new Dictionary<string, TopicFile>();
            }
            if(!topicFiles.ContainsKey(attachmentName))
            {
                TopicFile tmp = TopicFile.GetByTopicIdAndName(this.Id, attachmentName);
                if (tmp != null)
                {
                    topicFiles.Add(attachmentName, tmp);
                }
            }
            if (topicFiles.ContainsKey(attachmentName))
            {
                return topicFiles[attachmentName];
            }
            else
            {
                return null;
            }
        }

        public new void Update()
        {
            base.Update();
        }

        protected override object SaveChanges(ref object concurencyId, Base dal)
        {
            if (IsNewRecord)
            {
                Created = DateTime.Now;
            }
            int idOut = Id;
            string topicGroupNameOut = TopicGroupName;
            ((TopicDal)dal).Update(ref idOut, TopicGroupId, ref topicGroupNameOut, Name, ref sequence, Created, ref concurencyId);
            Id = idOut;
            TopicGroupName = topicGroupNameOut;

            return idOut;
        }

        public new void Delete()
        {
            base.Delete();
        }

        protected override void DeleteRecord(object concurencyId, Base dal)
        {
            ((TopicDal)dal).Delete(Id, concurencyId);
        }

        public static void Move(List<Topic> topics, int movingIndex, int replacingIndex)
        {
            //get the moving
            Topic moving = topics[movingIndex];
            //get the move to
            Topic replacing = topics[replacingIndex];

            bool saveAll = false;
            if (moving.Sequence == replacing.Sequence)
            {
                saveAll = true;
                for (int i = 0; i < topics.Count; i++)
                {
                    if (topics[i].Sequence != i)
                    {
                        topics[i].Sequence = i;
                    }
                }
            }

            int tmpSequence = moving.Sequence;
            moving.Sequence = replacing.Sequence;
            replacing.Sequence = tmpSequence;

            if (saveAll)
            {
                topics[0].BeginTransaction();
                foreach (Topic t in topics)
                {
                    if (t != topics[0])
                    {
                        t.UseTransaction(topics[0].TransactionKey);
                    }
                    t.Update();
                }
                topics[0].CommitTransaction();
            }
            else
            {
                moving.BeginTransaction();
                replacing.UseTransaction(moving.TransactionKey);
                moving.Update();
                replacing.Update();
                moving.CommitTransaction();
            }

        }


        private TopicGroup topicGroup;
        public TopicGroup TopicGroup
        {
            get 
            {
                if (topicGroup == null && TopicGroupId > 0)
                {
                    topicGroup = TopicGroup.GetById(TopicGroupId);
                }
                return topicGroup;
            }
        }

    }
}
